#include <physical/3d/temp_allocator.h>

#include <mimalloc.h>

#define JPH_ALIGN_UP(x) (((x)+15)&~15)

primal::PhysicalTempAllocator::PhysicalTempAllocator(u32 inSize):
	mBase{ static_cast<u8*>(mi_malloc_aligned(inSize,JPH_RVECTOR_ALIGNMENT)) },
	mSize{ inSize },
	mTop{}
{}

primal::PhysicalTempAllocator::~PhysicalTempAllocator()
{
	assert(mTop == 0);
	mi_free_aligned(mBase, JPH_RVECTOR_ALIGNMENT);
}

void* primal::PhysicalTempAllocator::Allocate(u32 inSize)
{
	if(inSize == 0)
	{
		return nullptr;
	}
	else
	{
		u32 new_top = mTop + JPH_ALIGN_UP(inSize);
		if(new_top > mSize)
		{
			return nullptr;
		}
		void* address = mBase + mTop;
		mTop = new_top;
		return address;
	}
}

void primal::PhysicalTempAllocator::Free(void* inAddress, u32 inSize)
{
	if(inAddress == nullptr)
	{
		JPH_ASSERT(inSize == 0);
	}
	else
	{
		mTop -= JPH_ALIGN_UP(inSize);
		if(mBase + mTop != inAddress)
		{
			
		}
	}
}

void* primal::phys::allocate_impl(size_t inSize)
{
	return mi_malloc(inSize);
}

void primal::phys::free_impl(void* inBlock)
{
	mi_free(inBlock);
}

void* primal::phys::aligned_allocate_impl(size_t inSize, size_t inAlignment)
{
	return mi_malloc_aligned(inSize, inAlignment);
}

void primal::phys::aligned_free_impl(void* inBlock)
{
	mi_free(inBlock);
}


